//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================


//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - S+S Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.IO;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Documents;
using System.Windows.Data;
using System.Globalization;

using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.SmartParts;
using Microsoft.Practices.CompositeUI.WPF;
using Microsoft.Practices.ObjectBuilder;
using Microsoft.Win32;

using LitwareHR.PublicApp.WinUX.Services;
using LitwareHR.Infrastructure.Interface;
using System.Windows.Media.Animation;
using Shp.Runtime.Contract;
using LitwareHR.PublicApp.WinUX.Entities;
using Microsoft.Practices.CompositeUI.Utility;
  
namespace LitwareHR.PublicApp.WinUX
{
    /// <summary>
    /// Interaction logic for OpenPositionView.xaml
    /// </summary>
    public partial class OpenPositionView : System.Windows.Controls.UserControl, IOpenPositionView, IDisposable
    {
        /// <summary>
        /// Initialize a new instance of <see cref="OpenPositionView"/>.
        /// <summary>
        
        public OpenPositionView()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(OnLoad);          
        }
        
        /// <summary>
        /// Called when WPF has loaded the control and is ready to display it.
        /// <summary>
        /// <param name="sender">Source of the event</param>
        /// <param name="e">Extra information about the event</param>
        public void OnLoad(object sender, RoutedEventArgs e)
        {
            _presenter.OnViewReady();

            InvalidProfileView.AddHandler(Control.MouseDoubleClickEvent, new RoutedEventHandler(HandleDoubleClick));
            FailedView.AddHandler(Control.MouseDoubleClickEvent, new RoutedEventHandler(HandleDoubleClick));
        }

        #region Form Events
        /// <summary>
        /// This 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnSave_Click(object sender, RoutedEventArgs e)
        {
            List<EntityField> entitySet = new List<EntityField>();

            for (int j = 0; j < SearchGrid.Children.Count; j = j + 4)
            {
                if (SearchGrid.Children[j].GetType() == typeof(TextBlock) && SearchGrid.Children[j + 2].GetType() == typeof(TextBlock) && SearchGrid.Children[j + 3].GetType() == typeof(TextBlock))
                {
                    EntityField field = new EntityField();
                    field.Name = ((TextBlock)SearchGrid.Children[j]).Text;
                    string strTemp = ((TextBlock)SearchGrid.Children[j + 2]).Text;
                    field.IsShared = strTemp.Length ==  4;
                    field.TypeName = ((TextBlock)SearchGrid.Children[j + 3]).Text;

                    Type objType = SearchGrid.Children[j + 1].GetType();
                    if (objType == typeof(TextBox))
                        field.Value = ((TextBox)SearchGrid.Children[j + 1]).Text;
                    else if (objType == typeof(CheckBox))
                        field.Value = ((CheckBox)SearchGrid.Children[j + 1]).IsChecked.ToString();
                    else if (objType == typeof(System.Windows.Forms.Integration.WindowsFormsHost))
                        field.Value = ((System.Windows.Forms.Integration.WindowsFormsHost)SearchGrid.Children[j + 1]).Child.Text.ToString();

                    entitySet.Add(field);
                }
            }

            _presenter.OnValidatePosition(entitySet);
        }

        /// <summary>
        /// This method is called when Cancel button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            for (int j = 0; j < SearchGrid.Children.Count; j = j + 4)
            {
                if (SearchGrid.Children[j].GetType() == typeof(TextBlock) &&
                    SearchGrid.Children[j + 2].GetType() == typeof(TextBlock) &&
                    SearchGrid.Children[j + 3].GetType() == typeof(TextBlock))
                {

                    if (SearchGrid.Children[j + 1].GetType() == typeof(TextBox))
                        ((TextBox)SearchGrid.Children[j + 1]).Text = string.Empty;
                    else if (SearchGrid.Children[j + 1].GetType() == typeof(CheckBox))
                        ((CheckBox)SearchGrid.Children[j + 1]).IsChecked = false;
                    else if (SearchGrid.Children[j + 1].GetType() == typeof(System.Windows.Forms.Integration.WindowsFormsHost))
                        ((System.Windows.Forms.Integration.WindowsFormsHost)SearchGrid.Children[j + 1]).Child.Text = DateTime.Today.ToShortDateString();
                }
            }
           
            ErrorTxt.Text = string.Empty;
            _presenter.ResetPositions();
        }

        /// <summary>
        /// This method is called when Save button of Bulk Import grid is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnBulkSave_Click(object sender, RoutedEventArgs e)
        {
            _presenter.SaveValidPositions();
        }

        /// <summary>
        /// This method is called on double click on records in "Failed" or "Error Entries" grid
        /// Depending on the grid appropriate error msg is displayed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void HandleDoubleClick(object sender, RoutedEventArgs e)
        {
            ListView listView = (ListView)sender;
            Position pos = (Position)(listView).SelectedItem;

            SetValuesToSearchGrid(pos);
            _presenter.SetPosition((listView).SelectedIndex, pos.PosType);

            ErrorTxt.Text = pos.Message;
        }

        #region Read Excel
        /// <summary>
        /// This method is called to open "Open File" dialog box for Bulk Import
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        public void OpenFileDialog(object sender, RoutedEventArgs args)
        {
            _presenter.OpenExcelFileAndImport();
        }

        #endregion

        #endregion

        #region IOpenPositionView Members

        public void LoadResources()
        {
            //Merge resoure directory
            base.Resources.MergedDictionaries.Add((ResourceDictionary)Application.LoadComponent(new Uri(@"Litware.HR;;;component/Views/Skins/BaseSkin.xaml", UriKind.Relative)));
        }

        public void SetupControls(EntityField[] list)
        {
            SetupSearchGrid(list);
        }

        public void ValidatePosition(List<EntityField> entitySet, EntityField[] positionFields)
        {
            Position pos = new Position(entitySet, positionFields);
            if (!pos.IsValid)
            {
                ErrorTxt.Text = pos.Message;
                return;
            }

            _presenter.OnSave(entitySet.ToArray());
            ErrorTxt.Text = string.Empty;
        }

        /// <summary>
        /// This method is used to Notify Schema Changes
        /// </summary>
        public void NotifySchemaChanges()
        {
            tbSchemaChanged.Visibility = Visibility.Visible;
            imgSchemaChanged.Visibility = Visibility.Visible;
            Storyboard StoryboardSchemaChanged = (Storyboard)FindResource("StoryboardSchemaChanged");
            StoryboardSchemaChanged.Begin(rootCanvas, true);
        }
        /// <summary>
        /// This method is used to Start Synchronization Animation
        /// </summary>
        public void StartSyncAnimation()
        {
            // throw new Exception("The method or operation is not implemented.");
            imgSync.Visibility = Visibility.Visible;
            tbSync.Visibility = Visibility.Visible;
            Storyboard storyboardRotation = (Storyboard)FindResource("StoryboardRotation");
            storyboardRotation.Begin(rootCanvas, true);
        }
        /// <summary>
        /// This method is used to Stop Synchronization Animation
        /// </summary>
        public void EndSyncAnimation()
        {
            Storyboard storyboardRotation = (Storyboard)FindResource("StoryboardRotation");
            storyboardRotation.Stop(rootCanvas);
            Storyboard StoryboardEndSyncAnimation = (Storyboard)FindResource("StoryboardEndSyncAnimation");
            StoryboardEndSyncAnimation.Begin(rootCanvas);
        }
        /// <summary>
        /// This method is called to dynamically create controls (textbox, checkbox etc) depending on the data type of tenant specific columns
        /// </summary>
        /// <param name="list"></param>
        private void SetupSearchGrid(EntityField[] list)
        {
            SearchGrid.BeginInit();
            SearchGrid.RowDefinitions.Clear();
            SearchGrid.ColumnDefinitions.Clear();
            SearchGrid.Children.Clear();
            
            CreateGridColumn(SearchGrid, new GridLength(60));
            CreateGridColumn(SearchGrid, new GridLength(250));

            int i = 0;
            foreach (EntityField field in list)
            {
                CreateGridRow(SearchGrid, new GridLength(25));
                CreateTextBlock(field.Name, i, 0, SearchGrid, Brushes.White);
                switch (field.TypeName)
                {                                       
                    case "Boolean (Yes | No)":
                        CreateCheckBox(field.Name, i, 1, SearchGrid);
                        break;
                    case "Date and time":
                        CreateDateTimePicker(field.Name, i, 1, SearchGrid);
                        break;
                    default:
                        CreateTextBox(field.Name, i, 1, SearchGrid);
                        break; 
                }
                TextBlock lblIsShared = CreateTextBlock(field.IsShared.ToString(), i, 1, SearchGrid, Brushes.White);
                lblIsShared.Visibility = Visibility.Hidden;

                TextBlock lblTypeName = CreateTextBlock(field.TypeName.ToString(), i, 1, SearchGrid, Brushes.White);
                lblTypeName.Visibility = Visibility.Hidden;

                i++;
            }

            if (list.Length > 0)
            {
                Style GlassyButtonStyle = (Style)FindResource("GlassyButtonStyle");
                
                CreateGridRow(SearchGrid, new GridLength(40));
                Button btnSave = CreateButton("btnSave", "Save", i, 1, SearchGrid);
                btnSave.Click += new RoutedEventHandler(btnSave_Click);
                btnSave.Style = GlassyButtonStyle;
                btnSave.HorizontalAlignment = HorizontalAlignment.Left;
                btnSave.Margin = new Thickness(30, 0, 0, 0);

                Button btnCancel = CreateButton("btnCancel", "Cancel", i, 1, SearchGrid);
                btnCancel.Click += new RoutedEventHandler(btnCancel_Click);
                btnCancel.HorizontalAlignment = HorizontalAlignment.Right;
                btnCancel.Style = GlassyButtonStyle;
                btnCancel.Margin = new Thickness(0, 0, 30, 0);
            }
            SearchGrid.EndInit();
        }

        /// <summary>
        /// This method is used to Set Values in the controls
        /// It is called when user double clicks on the records in "Failed" or "Error Entries" grid
        /// </summary>
        /// <param name="list"></param>
        private void SetValuesToSearchGrid(Position pos)
        {
            List<EntityField> entitySet = pos.Fields;
            EntityField[] list =  entitySet.ToArray();
          
            for (int j = 0; j < SearchGrid.Children.Count; j = j + 4)
            {
                if (SearchGrid.Children[j].GetType() == typeof(TextBlock) &&
                    SearchGrid.Children[j + 2].GetType() == typeof(TextBlock) &&
                    SearchGrid.Children[j + 3].GetType() == typeof(TextBlock))
                {

                    //Find this entity in list
                    bool found = false;
                    foreach (EntityField field in list)
                    {
                        if (field.Name.Equals(((TextBlock)SearchGrid.Children[j]).Text))
                        {
                            try
                            {
                                if (SearchGrid.Children[j + 1].GetType() == typeof(TextBox))
                                {
                                    ((TextBox)SearchGrid.Children[j + 1]).Text = field.Value;
                                    found = true; 
                                    break;
                                }
                                else if (SearchGrid.Children[j + 1].GetType() == typeof(System.Windows.Forms.Integration.WindowsFormsHost))
                                {
                                    ((System.Windows.Forms.Integration.WindowsFormsHost)SearchGrid.Children[j + 1]).Child.Text = field.Value;
                                    found = true; 
                                    break;
                                }
                                else if (SearchGrid.Children[j + 1].GetType() == typeof(CheckBox))
                                {
                                    ((CheckBox)SearchGrid.Children[j + 1]).IsChecked = pos.IsBoolean(field.Value);
                                    found = true; 
                                    break;
                                }
                            }
                            catch
                            {
                                //Typecast error for invalid entries for eg. Boolean field
                                break;
                            }
                        }
                    }
                    
                    if (!found)
                    {
                        if (SearchGrid.Children[j + 1].GetType() == typeof(TextBox))
                            ((TextBox)SearchGrid.Children[j + 1]).Text = string.Empty;
                        else if (SearchGrid.Children[j + 1].GetType() == typeof(System.Windows.Forms.Integration.WindowsFormsHost))
                            ((System.Windows.Forms.Integration.WindowsFormsHost)SearchGrid.Children[j + 1]).Child.Text = string.Empty;
                        else if (SearchGrid.Children[j + 1].GetType() == typeof(CheckBox))
                            ((CheckBox)SearchGrid.Children[j + 1]).IsChecked = false;
                    }
                }
            }
        }

        public void BindValidList(PositionCollection validList)
        {
            Guard.ArgumentNotNull(validList, "validList");

            if (validList.Count > 0) 
                BulkImportExpander.IsExpanded = true;

            ProfileView.DataContext = validList;
        }

        public void BindInvalidList(PositionCollection invalidList)
        {
            Guard.ArgumentNotNull(invalidList, "invalidList");
            if (invalidList.Count > 0) 
                ErrorExpander.IsExpanded = true;
            
            InvalidProfileView.DataContext = invalidList;
        }

        public void BindFailedList(PositionCollection failedList)
        {
            Guard.ArgumentNotNull(failedList, "failedList");

            if (failedList.Count > 0) 
                FailedExpander.IsExpanded = true;
            
            FailedView.DataContext = failedList;
        }

        public void BindQueuedList(PositionCollection queuedList)
        {
            Guard.ArgumentNotNull(queuedList, "queuedList");

            if (queuedList.Count > 0) 
                OutboxExpander.IsExpanded = true;

            OutboxView.DataContext = queuedList;
        }

        /// <summary>
        /// Used to create new textblock
        /// </summary>
        /// <param name="text"></param>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="grid"></param>
        /// <param name="brush"></param>
        /// <returns></returns>
        private static TextBlock CreateTextBlock(string text, int row, int col, Grid grid, SolidColorBrush brush)
        {
            TextBlock lbl = new TextBlock();
            lbl.Height = 20;
            lbl.Text = text;
            lbl.Foreground = brush;
            lbl.HorizontalAlignment = HorizontalAlignment.Right;
            lbl.VerticalAlignment = VerticalAlignment.Bottom;
            grid.Children.Add(lbl);
            Grid.SetColumn(lbl, col);
            Grid.SetRow(lbl, row);
            return lbl;
        }

        /// <summary>
        /// Used to create button
        /// </summary>
        /// <param name="name"></param>
        /// <param name="content"></param>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="grid"></param>
        /// <returns></returns>
        private static Button CreateButton(string name, string content, int row, int col, Grid grid)
        {
            //Create Show button
            Button btn = new Button();
            btn.Name = name;
            btn.Content = content;
            btn.Height = 25;
            btn.Width = 70;
            btn.HorizontalAlignment = HorizontalAlignment.Left;
            grid.Children.Add(btn);
            Grid.SetColumn(btn, col);
            Grid.SetRow(btn, row);
            return btn;
        }
        /// <summary>
        /// Used to create textbox
        /// </summary>
        /// <param name="name"></param>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="grid"></param>
        private void CreateTextBox(string name, int row, int col, Grid grid)
        {
            TextBox txtbxControl = new TextBox();
            txtbxControl.Width = 220;
            txtbxControl.Height = 20;
            txtbxControl.Name = name;
            txtbxControl.HorizontalAlignment = HorizontalAlignment.Center;                        
            SearchGrid.Children.Add(txtbxControl);
            Grid.SetColumn(txtbxControl, col);
            Grid.SetRow(txtbxControl, row);
        }
        /// <summary>
        /// Used to create checkbox
        /// </summary>
        /// <param name="name"></param>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="grid"></param>
        private void CreateCheckBox(string name, int row, int col, Grid grid)
        {
            CheckBox chkbxControl = new CheckBox();
            chkbxControl.Width = 30;
            chkbxControl.Height = 20;
            chkbxControl.Name = name;
            chkbxControl.HorizontalAlignment = HorizontalAlignment.Left;
            chkbxControl.Margin = new Thickness(14,7, 0, 0);
            SearchGrid.Children.Add(chkbxControl);
            Grid.SetColumn(chkbxControl, col);
            Grid.SetRow(chkbxControl, row);            
        }      
        /// <summary>
        /// Used to create DateTimePicker
        /// </summary>
        /// <param name="name"></param>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="grid"></param>
        private void CreateDateTimePicker(string name, int row, int col, Grid grid)
        {                       
            System.Windows.Forms.Integration.WindowsFormsHost host = new System.Windows.Forms.Integration.WindowsFormsHost();
            System.Windows.Forms.DateTimePicker dtPickerControl = new System.Windows.Forms.DateTimePicker();
            dtPickerControl.Name = name;
            dtPickerControl.Width = 100;
            dtPickerControl.Margin = new System.Windows.Forms.Padding(40);
            dtPickerControl.MaximumSize = new System.Drawing.Size(220, 20);
            dtPickerControl.Format = System.Windows.Forms.DateTimePickerFormat.Short;
            host.Child = dtPickerControl;
            SearchGrid.Children.Add(host);
            Grid.SetColumn(host, col);            
            Grid.SetRow(host, row);            
        }      
        /// <summary>
        /// Used to create Grid column
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="width"></param>
        private static void CreateGridColumn(Grid grid, GridLength width)
        {
            ColumnDefinition col = new ColumnDefinition();
            col.Width = width;            
            grid.ColumnDefinitions.Add(col);
        }
        /// <summary>
        /// Used to create Grid row
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="height"></param>
        private void CreateGridRow(Grid grid, GridLength height)
        {
            RowDefinition row = new RowDefinition();
            row.Height = height;
            grid.RowDefinitions.Add(row);
        }

        #endregion
    }
}

